using System.Collections.Generic;
using UnityEngine;

namespace UFrame
{
    /// <summary>
    /// UGUI clip model
    /// </summary>
    public class UGUIClip : MonoBehaviour
    {
        public RectTransform content = null;
        public GameObject targetNode;
        public bool isEnable = true;
        private bool isOne;
        public Shader[] replaceShader;

        private void Awake()
        {
            if (targetNode != null)
            {
                Clip(targetNode);
            }
        }

        private void OnEnable()
        {
            if (isEnable && !isOne)
            {
                Clip();
                isOne = true;
            }
        }

        public void Clip(GameObject target = null)
        {
            if (content == null)
            {
                content = GetComponent<RectTransform>();
            }

            Vector3[] corners = new Vector3[4];
            RectTransform rectTransform = content as RectTransform;
            rectTransform.GetWorldCorners(corners);
            float minX = corners[0].x;
            float minY = corners[0].y;
            float maxX = corners[2].x;
            float maxY = corners[2].y;

            Renderer[] rAry = null;
            if (target != null)
            {
                rAry = target.GetComponentsInChildren<Renderer>(true);
            }
            else
            {
                rAry = transform.GetComponentsInChildren<Renderer>(true);
            }


            Shader s = null;

            Renderer item = null;
            Material m = null;

            Dictionary<string, Shader> shaderDic = new Dictionary<string, Shader>();

            for (int z = 0; z < replaceShader.Length; z++)
            {
                shaderDic.Add(replaceShader[z].name, replaceShader[z]);
            }

            for (int i = 0; i < rAry.Length; i++)
            {
                item = rAry[i];

                var mAry = item.sharedMaterials;
                for (int j = 0; j < mAry.Length; j++)
                {
                    m = mAry[j];

                    var name = m.shader.name;
                    bool alreadyClip = name.EndsWith("_Clip");
                    string nameClip = alreadyClip ? name : name + "_Clip";
                    bool isFind = false;

                    if (!alreadyClip && shaderDic.ContainsKey(nameClip))
                    {
                        s = shaderDic[nameClip];
                        isFind = true;
                    }

                    if (!isFind)
                    {
                        continue;
                    }

                    if (!alreadyClip)
                    {
                        m.shader = s;
                    }

                    if (m.HasProperty("_MinX"))
                    {
                        m.SetFloat("_MinX", minX);
                        m.SetFloat("_MinY", minY);
                        m.SetFloat("_MaxX", maxX);
                        m.SetFloat("_MaxY", maxY);
                    }
                }
            }
        }
    }
}